/** 样式键 */
type Tdom_style_key = keyof CSSStyleDeclaration;
/** 样式值 */
type Tdom_style_value = Tvalue;
/** 样式配置对象 */
type Tdom_style_obj = Partial<{
    [key in Tdom_style_key]: Tdom_style_value;
}>;

interface KHTMLElement {
    /**
     * 设置样式
     * @param styles 样式对象
     */
    setStyle(styles: Tdom_style_obj): KHTMLElement;
    /**
     * 设置样式
     * @param key 样式键
     * @param value 样式值
     * @description value: undefined => 无操作
     * @description value: null => 删除样式
     * @description value: others => 设置样式
     */
    setStyle(key: Tdom_style_key, value: Tdom_style_value): KHTMLElement;
}
{
    Object.defineProperty(KHTMLElement.prototype, 'setStyle', {
        writable: false,
        configurable: false,
        enumerable: false,
        value: U.F.overloading('DOM-setStyle',
            {
                types: [Etype.obj],
                fn: function (this: KHTMLElement, styles: any) {
                    for (const key in styles) {
                        if (Object.prototype.hasOwnProperty.call(styles, key)) {
                            this.setStyle(key as keyof CSSStyleDeclaration, styles[key]);
                        }
                    }
                    return this
                }
            },
            {
                types: [Etype.string, Etype.undefined],
                fn: U.F.fn.this
            },
            {
                types: [Etype.string, Etype.null],
                fn: function (this: KHTMLElement, key: string) {
                    this.elements.forEach(ele => {
                        ele.style.removeProperty(U.S.snakeCase(key, '-'));
                    });
                    return this
                }
            },
            {
                types: [Etype.string, Etype.string],
                fn: function (this: KHTMLElement, key: string, value: string) {
                    this.elements.forEach(ele => {
                        ele.style.setProperty(U.S.snakeCase(key, '-'), value);
                    });
                    return this
                }
            },
            {
                types: [Etype.string, [Etype.boolean, Etype.number]],
                fn: function (this: KHTMLElement, key: keyof CSSStyleDeclaration, value: any) {
                    this.setStyle(key, String(value));
                    return this
                }
            },
        )
    });
}
